package cn.stylefeng.guns.modular.quan.service.impl;

import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.core.util.QRCodeUtil;
import cn.stylefeng.guns.core.util.StrUtil;
import cn.stylefeng.guns.modular.bshuser.entity.BshUsers;
import cn.stylefeng.guns.modular.bshuser.service.BshUsersService;
import cn.stylefeng.guns.modular.quan.entity.Coupon;
import cn.stylefeng.guns.modular.quan.entity.CouponCode;
import cn.stylefeng.guns.modular.quan.entity.CouponReceive;
import cn.stylefeng.guns.modular.quan.mapper.CouponReceiveMapper;
import cn.stylefeng.guns.modular.quan.model.params.CouponReceiveParam;
import cn.stylefeng.guns.modular.quan.model.result.CouponReceiveResult;
import cn.stylefeng.guns.modular.quan.service.CouponCodeService;
import  cn.stylefeng.guns.modular.quan.service.CouponReceiveService;
import cn.stylefeng.guns.modular.quan.service.CouponService;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.response.ResponseData;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Dong
 * @since 2023-10-31
 */
@Service
public class CouponReceiveServiceImpl extends ServiceImpl<CouponReceiveMapper, CouponReceive> implements CouponReceiveService {

    @Autowired
    private BshUsersService bshUsersService;
    @Autowired
    private CouponReceiveService couponReceiveService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private CouponCodeService couponCodeService;

    Queue<String> queue = new ConcurrentLinkedQueue<>();
    final ReentrantLock lock = new ReentrantLock();


    @Override
    public void add(CouponReceiveParam param){
        CouponReceive entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(CouponReceiveParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(CouponReceiveParam param){
        CouponReceive oldEntity = getOldEntity(param);
        CouponReceive newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public CouponReceiveResult findBySpec(CouponReceiveParam param){
        return null;
    }

    @Override
    public List<CouponReceiveResult> findListBySpec(CouponReceiveParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(CouponReceiveParam param){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public Object receiveCoupon(String userId, Long couponId) {
        queue.offer(userId);

        FutureTask task = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                while (true) {
//                    int size = queue.size();
//                    try {
//                        lock.lock();
                        if (!queue.isEmpty()) {
                            String poll = queue.poll();
                            BshUsers user = bshUsersService.getOne(new QueryWrapper<BshUsers>()
                                    .eq("user_id",poll));

                            if (user == null) {
                                return ResponseData.error(1001, "非法用户");
                            }
                            CouponReceive couponReceive = couponReceiveService.getOne(new QueryWrapper<CouponReceive>()
                                    .eq("user_id",userId).eq("coupon_id",couponId)
                                    .eq("is_delete",0)
                                    .last(" order by id asc"));
                            if (couponReceive != null) {
                                return ResponseData.error(1002, "不可重复领取");
                            }

                            Coupon couponDetail = couponService.getById(couponId);
                            Date date = new Date();

                            if (date.compareTo(couponDetail.getEndTime()) > 0) {
                                return ResponseData.error(1004, "优惠券已失效，不可领取");
                            }

                            if (couponDetail.getRemainingQuantity() <= 0) {
                                return ResponseData.error(1005, "优惠券已全部领完");
                            }


                            if (couponDetail.getStatus() == 0) {
                                String fileName = UUID.randomUUID().toString().replace("-", "");
                                String text = System.currentTimeMillis() + "";
                                String qrcode = QRCodeUtil.getQrcode(text, 300, 300, fileName + ".png");
                                couponReceive = new CouponReceive();
                                couponReceive.setUserId(poll);
                                couponReceive.setCouponId(couponId);
                                couponReceive.setQrTag(text);
                                couponReceive.setQrCode(qrcode);
                                couponReceive.setCreateTime(new Date());
                                //减券
                                int remainingQuantity = couponService.jianquan(couponId);
                                if (remainingQuantity > 0) {
                                    couponReceiveService.save(couponReceive);
                                } else {
                                    return ResponseData.error(1005, "优惠券已全部领完");
                                }
                            } else {
                                CouponCode couponCodeEnt = couponCodeService.getOne(new QueryWrapper<CouponCode>()
                                        .eq("coupon_id",couponId).eq("is_delete",0).eq("is_used",0).last(" limit 1"));

                                if (couponCodeEnt==null) {
                                    return ResponseData.error(1005, "优惠券已全部领完");
                                }

                                String couponCode = couponCodeEnt.getCode();

                                if (StrUtil.isEmpty(couponCode)) {
                                    return ResponseData.error(1005, "优惠券已全部领完");
                                }
                                int code = couponCodeService.jianquan(couponId,couponCode);
                                if (code > 0) {
                                    couponReceive = new CouponReceive();
                                    couponReceive.setUserId(poll);
                                    couponReceive.setCouponId(couponId);
                                    couponReceive.setCouponCode(couponCode);
                                    couponReceive.setCreateTime(new Date());
                                    int remainingQuantity = couponService.jianquan(couponId);
                                    if (remainingQuantity > 0) {
                                        couponReceiveService.save(couponReceive);
                                    }
                                } else {
                                    return ResponseData.error(1005, "优惠券已全部领完");
                                }
                            }

                        } else {
                            break;
                        }
//                    } finally {
//                        lock.unlock();
//                    }
                }

                Map<String,Object> first = couponReceiveService.getFrist(userId,couponId);
                return ResponseData.success(first);
            }
        });
        Thread t = new Thread(task);

        t.start();
        try {
            return task.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return ResponseData.error(99998,"当前人数过多，请稍后重试");
        } catch (ExecutionException e) {
            e.printStackTrace();
            return ResponseData.error(99999,"当前人数过多，请稍后重试");
        }
    }

    @Override
    public Object getCouponById(String userId) {
        return this.baseMapper.getCouponById(userId);
    }

    @Override
    public Object getCouponDetailByUser(String userId, Long couponId) {
        return this.baseMapper.getCouponDetailByUser(userId, couponId);
    }

    @Override
    public Map<String, Object> getFrist(String userId, Long couponId) {
        return this.baseMapper.getFrist(userId, couponId);
    }

    private Serializable getKey(CouponReceiveParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private CouponReceive getOldEntity(CouponReceiveParam param) {
        return this.getById(getKey(param));
    }

    private CouponReceive getEntity(CouponReceiveParam param) {
        CouponReceive entity = new CouponReceive();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

}
